package com.iuie.ns.devtools.element;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.iuie.ns.devtools.to.DevBodyTO;
import com.iuie.ns.devtools.to.ResultMapDevHeaderTO;
import com.iuie.ns.frame.utils.ListUtils;

public abstract class ResultMapOperationElement extends DevElement{

	private ResultMapDevHeaderTO header;
	
	private List<? extends DevBodyTO> bodys;
	
	private Map<String, String> fieldTypeRelationMap;
	
	private String operation;
	
	// getter...setter...
	public ResultMapDevHeaderTO getHeader() {
		return header;
	}
	public void setHeader(ResultMapDevHeaderTO header) {
		this.header = header;
	}
	public String getOperation() {
		return operation;
	}
	public void setOperation(String operation) {
		this.operation = operation;
	}
	public List<? extends DevBodyTO> getBodys() {
		return bodys;
	}
	public void setBodys(List<? extends DevBodyTO> bodys) {
		this.bodys = bodys;
	}
	public Map<String, String> getFieldTypeRelationMap() {
		return fieldTypeRelationMap;
	}
	public void setFieldTypeRelationMap(Map<String, String> fieldTypeRelationMap) {
		this.fieldTypeRelationMap = fieldTypeRelationMap;
	}
	
	/**
	 * 循环bodys的小工具
	 * @author iuie
	 *
	 */
	public abstract static class EachBodys {
		
		public EachBodys(List<? extends DevBodyTO> bodys) {
			if (ListUtils.isNotEmpty(bodys)) {
				int size = bodys.size();
				for (int i = 0; i < size; i++ ) {
					each(i, bodys.get(i), i == 0, i == size - 1, size);
				}
			}
		}
		public abstract void each(int i, DevBodyTO body, boolean isFirst, boolean isEnd, int size);
	}
	
	public DevElement getSQLFieldElement() {
		final StringBuilder sb = new StringBuilder(12);
		new EachBodys(this.bodys) {

			@Override
			public void each(int i, DevBodyTO body, boolean isFirst, boolean isEnd, int size) {
				sb.append(body.getFieldName());
				if (!isEnd) {
					sb.append(",");
				}
				sb.append(" ");
			}
			
		};
		return new BaseDevElement(sb.toString());
	}
	
	public String getTabs(int tabs, boolean newLine) {
		StringBuilder sb = new StringBuilder(3);
		if (newLine) {
			sb.append("\n");
		}
		for (int i = 0; i < tabs; i ++) {
			sb.append("\t");
		}
		return sb.toString();
	}
	
	public DevElement getTabsElement(int tabs, boolean newLine) {
		return new BaseDevElement(this.getTabs(tabs, newLine));
	}
	
	/**
	 * 获取字符串形如: #{userId, jdbcType=BIGINT}，插入语句中要用到
	 * @return
	 */
	public List<DevElement> getMyBatisValueElements(final int tabs) {
		final List<DevElement> list = new ArrayList<>();
		new EachBodys(this.bodys) {
			
			@Override
			public void each(int i, DevBodyTO body, boolean isFirst, boolean isEnd, int size) {
				list.add(body.getValueItemElement(true));
				if (!isEnd) {
					list.add(new BaseDevElement(", "));
				}
				if ((i + 1) % 3 == 0 && (i + 1) != size) {
					list.add(getTabsElement(tabs, true));
				}
			}
		};
		return list;
	}
	
	/**
	 * 获取字符串形如： user_id=#{userId, jdbcType=BIGINT} 
	 * @return
	 */
	public List<DevElement> getMyBatisUpdateEqualValueElements() {
		final List<DevElement> list = new ArrayList<>();
		new EachBodys(this.bodys) {
			
			@Override
			public void each(int i, DevBodyTO body, boolean isFirst, boolean isEnd, int size) {
				if (body.isDoUpdateAttribute()) {
					list.add(body.getMyBatisEqualElement(true));
					list.add(new BaseDevElement(", " + getTabs(3, true)));
				}
			}
		};
		if (list.size() > 0) {
			list.remove(list.size() - 1);
		}
		return list;
	}
	
	/**
	 * 获取主键/联合主键
	 * @return
	 */
	public List<DevBodyTO> getPrimaryKeys() {
		final List<DevBodyTO> primaryKeys =  new ArrayList<>();
		new EachBodys(this.bodys) {
			
			@Override
			public void each(int i, DevBodyTO body, boolean isFirst, boolean isEnd, int size) {
				if (body.isIdAttribute()) {
					primaryKeys.add(body);
				}
			}
		};
		return primaryKeys;
	}
	
	
	/**
	 * 获取形如：user_id=#{userId, jdbcType=BIGINT} and user_name=#{userName, jdbcType=VARCHAR}
	 * @return
	 */
	public List<DevElement> getPrimaryKeyEqualValueElements(boolean withItem) {
		final List<DevElement> list = new ArrayList<>();
		List<DevBodyTO> primaryKeys = this.getPrimaryKeys();
		
		if (ListUtils.isNotEmpty(primaryKeys)) {
			String prefix = null;
			Iterator<DevBodyTO> it = primaryKeys.iterator();
			while (it.hasNext()) {
				DevBodyTO body = it.next();
				DevElement item = new BaseDevElement(prefix, body.getMyBatisEqualElement(withItem), " ");
				list.add(item);
				prefix = "\n\t\tand ";
			}
		}
		return list;
	}
	
	/**
	 * 获取查询条件
	 * @return
	 */
	public List<DevElement> getQueryConditionElements() {
		final List<DevElement> list = new ArrayList<>();
		new EachBodys(this.bodys) {
			
			@Override
			public void each(int i, DevBodyTO body, boolean isFirst, boolean isEnd, int size) {
				if (body.isDoQueryAttribute()) {
					list.add(body.getTestConditionElement());
				}
			}
		};
		return list;
	}
	
}
